package cn.lili.util;

import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.Calendar;

public class ToolsUtil {


    /**
     * 获取异常详情
     * @param e
     * @return
     */
    public static String getExceptionSrintStackTrace(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString();
    }


    /**
     * 获取ip地址
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) {
                // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress="";
        }
        return ipAddress;
    }


    /**
     * 计算两个日期之间的月份差
     * @param startDate
     * @param endDate
     * @return
     */
    public static int monthsBetween(Date startDate, Date endDate) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);

        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);

        int startYear = startCalendar.get(Calendar.YEAR);
        int startMonth = startCalendar.get(Calendar.MONTH);

        int endYear = endCalendar.get(Calendar.YEAR);
        int endMonth = endCalendar.get(Calendar.MONTH);

        // 计算年份差和月份差
        int monthsBetween = (endYear - startYear) * 12 + (endMonth - startMonth);

        // 考虑月份的精确性，如果 endDate 的日期小于 startDate 的日期，则需要减去一个月
        if (endCalendar.get(Calendar.DAY_OF_MONTH) < startCalendar.get(Calendar.DAY_OF_MONTH)) {
            monthsBetween--;
        }
        return monthsBetween;
    }


    /**
     * 增加月数
     * @param date
     * @param months
     * @return
     */
    public static Date addMonths(Date date, int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, months);
        return calendar.getTime();
    }

    /**
     * 减少月数
      * @param date
     * @param months
     * @return
     */
    public static Date subtractMonths(Date date, int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -months);
        return calendar.getTime();
    }

    /**
     * 增加天数
     * @param date
     * @param days
     * @return
     */
    public static Date addDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, days);
        return calendar.getTime();
    }

    /**
     * 减少天数
     * @param date
     * @param days
     * @return
     */
    public static Date subtractDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, -days);
        return calendar.getTime();
    }


    /**
     * 处理日期
     */
    public static LocalDateTime processLocalDateTimeParam(String date, boolean isStartTime) {
        if (date == null || date.isEmpty()) {
            // 获取当前日期
            LocalDate currentDate = LocalDate.now();

            if (isStartTime) {
                // 返回当月的第一天的00点
                return currentDate.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay();
            } else {
                // 返回当月的最后一天的最大时间
                return currentDate.with(TemporalAdjusters.lastDayOfMonth()).atTime(23, 59, 59, 999999999);
            }
        } else {
            // 如果日期参数不为空，则解析日期字符串为 LocalDateTime 对象
            LocalDate dateTime = LocalDate.parse(date);

            if (isStartTime) {
                // 返回给定日期的00点
                return dateTime.atStartOfDay();
            } else {
                // 返回给定日期的最大时间
                return dateTime.atTime(23, 59, 59, 999999999);
            }
        }
    }


    /**
     * 获取当前时间到凌晨0点还剩多少秒
     *
     * @returnUSER_ACTIVE_MONTH
     */
    public static Long get0SpotSeconds() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }
}
